﻿using System.Collections.Generic;
using System.ComponentModel;
using System.IO;
using System.Text;
using PPI.Client.Logic.Delegate;
using PPI.Controls;
using PPI.Entities;
using PPI.Entities.Distribution;
using PPI.Entities.Inspections;
using PPI.Entities.Interface;
using PPI.Entities.Kml;
using PPI.Entities.Polygon;
using PPI.Entities.Remedy;
using PPI.Entities.Settings;
using PPI.Entities.Utility;


namespace PPI
{
    public class GEHelper
    {
        private List<EKmlFile> m_KmlFiles;
        private List<EVendor_Visit_XMissionStructure> m_Visits;
        private List<EInspectionResult> m_InspectionResults;
        private List<EInspectionStructure> m_InspectionStructures;
        private List<EUtility_Asset_XMissionStructure> m_Assets;
        private List<EDistributionPole> m_Poles;
        private GoogleEarthViewPort m_ViewPort;
        private List<EUtility_Polygon> m_Polygons = null;
        private BackgroundWorker m_worker;
        private ESettingsCustomInspectionKml  m_CustomKml;

        private bool m_ShowAsset;
        private bool m_ShowGPS;
        private bool m_ShowInspection;
        private bool m_ShowPolygons;
        private bool m_ShowInspectionStructures;
        private bool m_ShowCustomKml;
        private bool m_ShowDistributionPoles;
        

        public bool ShowCustomKml
        {
            set { m_ShowCustomKml = value; }
        }

        private string m_generatedCode;
        private UpdateBar m_delegateBar;
        private UpdateMessage m_delegateMessage;


        public List<EVendor_Visit_XMissionStructure> Visits
        {
            get
            {
                return m_Visits;
            }
            set
            {
                m_Visits = value;
            }
        }
        public List<EInspectionResult> InspectionResults
        {
            get { return m_InspectionResults; }
            set { m_InspectionResults = value; }
        }
        public List<EUtility_Asset_XMissionStructure> Assets
        {
            get { return m_Assets; }
            set { m_Assets = value; }
        }
        public List<EUtility_Polygon> Polygons
        {
            get { return m_Polygons; }
            set { m_Polygons = value; }
        }
        public List<EDistributionPole> Poles
        {
            get
            {
                return m_Poles;
            }
            set
            {
                m_Poles = value;
            }
        }

        public bool ShowPolygons
        {
            set { m_ShowPolygons = value; }
        }

        public bool ShowGPS
        {
            set
            {
                m_ShowGPS = value;
            }
        }

        public bool ShowInspection
        {
            set
            {
                m_ShowInspection = value;
            }
        }

        public bool ShowAsset
        {
            get { return m_ShowAsset; }
            set { m_ShowAsset = value; }
        }

        public bool ShowDistributionPoles
        {
            get { return m_ShowDistributionPoles; }
            set { m_ShowDistributionPoles = value; }
        }

        public ESettingsCustomInspectionKml CustomKml
        {
            get { return m_CustomKml; }
            set { m_CustomKml = value; }
        }


        public void ExecuteKML()
        {
            if(m_Visits != null && m_ShowGPS)
                AssetsToKmlfile(m_Visits);
            if (m_InspectionResults != null && m_ShowInspection)
                InspectionsToKmlFile();
            if (m_Polygons != null && m_ShowPolygons)
                PolygonsToKmlFile();
            if (m_ShowInspectionStructures && m_InspectionStructures != null)
                InspectionStructuresToKmlFile();

            if(m_Assets != null && m_ShowAsset)
                AssetsToKmlFile();

            if(m_ShowCustomKml && m_CustomKml != null)
                m_KmlFiles.Add(new EKmlFile(m_CustomKml.SettingText));

            if (m_ShowDistributionPoles && m_Poles != null)
                DistributionPolesToKmlFile();

            m_worker.RunWorkerAsync();
        }

        public void ExecuteKML(ERemedy remedy)
        {
            m_KmlFiles.Clear();
            m_KmlFiles.Add(remedy.ToKml());
            foreach (EInspectionImage image in remedy.Inspection.Images)
            {
                m_KmlFiles.Add(image.ToKml());
            }
            m_worker.RunWorkerAsync();
        }

        public void ExecuteKML(EBasePosition baseVisit)
        {
            m_KmlFiles.Clear();
            m_KmlFiles.Add(baseVisit.ToKml());
            m_worker.RunWorkerAsync();
        }
        public void ExecuteKML(EInspectionStructure structure)
        {
            m_KmlFiles.Clear();
            foreach (EInspection i in structure.Inspections)
            {
                m_KmlFiles.Add(i.ToKml());
                foreach (EInspectionImage image in i.Images)
                {
                    m_KmlFiles.Add(i.ToKml());
                }
            }
            m_worker.RunWorkerAsync();
        }

        public void ExecuteKML(EVendor_Visit_XMissionStructure structure)
        {
            m_KmlFiles.Clear();
            m_KmlFiles.Add(structure.ToKml());
            foreach (EVendor_Visit_XMissionStructures_Image image in structure.Images)
            {
                m_KmlFiles.Add(image.ToKml());
            }
            m_worker.RunWorkerAsync();
        }

        public void ExecuteKML(EUtility_Asset_XMissionStructure asset)
        {
            m_KmlFiles.Clear();
            m_KmlFiles.Add(asset.ToKml());
            foreach (EBasePosition position in asset.VisitGps)
            {
                EVendor_Visit_XMissionStructure tmpStructure = (EVendor_Visit_XMissionStructure) position;
                m_KmlFiles.Add(tmpStructure.ToKml());
                foreach (EVendor_Visit_XMissionStructures_Image image in tmpStructure.Images)
                {
                    m_KmlFiles.Add(image.ToKml());
                }
            }

            foreach (EBasePosition position in asset.VisitInspections)
            {
                EInspectionStructure tmpStructure = (EInspectionStructure) position;
                foreach (EInspection inspection in tmpStructure.Inspections)
                {
                    m_KmlFiles.Add(inspection.ToKml());
                    foreach (EInspectionImage image in inspection.Images)
                    {
                        m_KmlFiles.Add(image.ToKml());
                    }
                }
            }

            m_worker.RunWorkerAsync();
        }

        private void AssetsToKmlFile()
        {
            foreach (EUtility_Asset_XMissionStructure asset in m_Assets)
            {
                ObjectToKml(asset);
            }
        }

        private void InspectionStructuresToKmlFile()
        {
            foreach (EInspectionStructure structure in m_InspectionStructures)
            {
                foreach (EInspection inspection in structure.Inspections)
                {
                    ObjectToKml(inspection);

                    foreach (EInspectionImage i in inspection.Images)
                    {
                        ObjectToKml(i);
                    }
                }
            }
        }

        private void DistributionPolesToKmlFile()
        {
            foreach (EDistributionPole pole in m_Poles) 
            {
                ObjectToKml(pole);


                foreach (EDistributionPoleImage poleImage in pole.Images)
                    ObjectToKml(poleImage);

                foreach (EMeter meter in pole.Meters)
                    if (meter.Image.FileName != string.Empty)
                        ObjectToKml(meter.Image);
            }
        }

        private void PolygonsToKmlFile()
        {
            foreach (EUtility_Polygon p in m_Polygons)
            {
                ObjectToKml(p);
            }
        }

        private void AssetsToKmlfile(List<EVendor_Visit_XMissionStructure> Assets)
        {
            foreach (EVendor_Visit_XMissionStructure a in Assets)
            {
                ObjectToKml(a);
                foreach (EBaseImage i in a.Images)
                {
                    ObjectToKml(i);
                }
            }
        }

        private void InspectionsToKmlFile()
        {
            foreach (EInspectionResult result in m_InspectionResults)
            {
                ObjectToKml(result);
                foreach (EInspectionImage i in result.Inspection.Images)
                {
                    ObjectToKml(i);   
                }
            }
        }


        public bool ShowInspectionStructures
        {
            get { return m_ShowInspectionStructures; }
            set { m_ShowInspectionStructures = value; }
        }

        public List<EInspectionStructure> InspectionStructures
        {
            get { return m_InspectionStructures; }
            set { m_InspectionStructures = value; }
        }

        public GEHelper(GoogleEarthViewPort viewPort, UpdateBar barDelegate)
        {
            m_delegateBar = barDelegate;
            m_KmlFiles = new List<EKmlFile>();
            m_ViewPort = viewPort;
            m_worker = new BackgroundWorker();
            m_worker.WorkerReportsProgress = true;
            m_worker.WorkerSupportsCancellation = false;
            m_worker.DoWork += new DoWorkEventHandler(m_worker_DoWork);
            m_worker.RunWorkerCompleted += new RunWorkerCompletedEventHandler(m_worker_RunWorkerCompleted);
            m_worker.ProgressChanged += new ProgressChangedEventHandler(m_worker_ProgressChanged);
        }



        void m_worker_RunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e)
        {
            if(m_delegateBar != null)
                m_delegateBar(100);
            GEHelper.WriteKMLFile(m_generatedCode, Constants.k_Filename);
            m_ViewPort.OpenKmlFile(Constants.k_Filename, 1);
            m_KmlFiles.Clear();

        }

        void m_worker_DoWork(object sender, DoWorkEventArgs e)
        {
           m_generatedCode = GenerateKMLFile(ref m_KmlFiles);
        }

        public string GenerateKMLFile(ref List<EKmlFile> m_KMLItems)
        {
            int _counter = 0;
            StringBuilder xmlText = new StringBuilder();
            string _KMLFile = "<?xml version=\"1.0\" encoding=\"UTF-8\"?>" +
                                    "<kml xmlns=\"http://earth.google.com/kml/2.2\">" +
                                    "<Document>" +
                                        "<name id=\"test1\">Poleposition icons</name>";
            xmlText.AppendLine(_KMLFile);
            foreach (EKmlFile _KMLItem in m_KMLItems)
            {
                xmlText.AppendLine(_KMLItem.KMLCode);
                m_worker.ReportProgress((_counter * 100) / m_KMLItems.Count);
                _counter++;
            }
            
            xmlText.AppendLine("</Document></kml>");

            //m_KMLItems = new List<EKmlFile>();
            return xmlText.ToString();
        }

        void m_worker_ProgressChanged(object sender, ProgressChangedEventArgs e)
        {
            if (m_delegateBar != null)
                m_delegateBar(e.ProgressPercentage);
        }

        private void ObjectToKml(IGoogleEarth o)
        {
            m_KmlFiles.Add(o.ToKml());
        }

        public static void WriteKMLFile(string _Content, string m_Filename)
        {
            FileStream _File = new FileStream(m_Filename, FileMode.Create, FileAccess.Write);
            StreamWriter sw = new StreamWriter(_File);
            sw.Write(_Content);
            sw.Close();
            _File.Close();
        }

        public void Clean()
        {
            m_KmlFiles.Clear();
            string _KMLFile = "<?xml version=\"1.0\" encoding=\"UTF-8\"?><kml xmlns=\"http://earth.google.com/kml/2.1\"></kml>";
            GEHelper.WriteKMLFile(_KMLFile, Constants.k_Filename);
            m_ViewPort.OpenKmlFile(Constants.k_Filename, 1);
        }
    }
}
